package net.easyjava.third.sms.zhutong;

import net.easyjava.third.sms.zhutong.constans.ZhuTongConstans;
import net.easyjava.third.sms.zhutong.exception.ZhuTongSMSException;
import net.easyjava.tools.lang.StringTools;
import net.easyjava.tools.security.md5.Md5Tools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.*;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Created by ludi on 16/7/26.
 */
public class ZhuTongSMSClient {
    private Logger logger = LoggerFactory.getLogger(ZhuTongSMSClient.class);

    private String username;
    private String password;
    private String codeProductId;
    private String messageProductId;

    /**
     * 构造单例
     */
    private volatile static ZhuTongSMSClient singleton;
    private ZhuTongSMSClient(String username, String password,String codeProductId,String messageProductId) {
        this.username = username;
        this.password = password;
        this.codeProductId = codeProductId;
        this.messageProductId = messageProductId;
    }

    public static ZhuTongSMSClient getInstance(final String username,final String password,final String codeProductId,final String messageProductId) {
        if (singleton == null) {
            synchronized (ZhuTongSMSClient.class) {
                if (singleton == null) {
                    singleton =  new ZhuTongSMSClient(username, password,codeProductId,messageProductId);
                }
            }
        }
        return singleton;
    }

    /**
     * 发送验证码
     * @param mobile
     * @param content
     * @return 返回发送成功/失败
     */
    public void sendCode(String mobile, String content) throws IOException, ZhuTongSMSException, NoSuchAlgorithmException {
        Map paramentMap = new LinkedHashMap();
        String strtime = new SimpleDateFormat("yyyyMMddHHmmss").format(System.currentTimeMillis());
        paramentMap.put("username", username);
        String pass = Md5Tools.md5(Md5Tools.md5(password) + strtime);
        paramentMap.put("tkey",  strtime);
        paramentMap.put("password", pass);//加密后密码
        paramentMap.put("productid", codeProductId);//   验证码专用产品id
        paramentMap.put("mobile", mobile);//号码
        paramentMap.put("content",  content);//内容
        paramentMap.put("xh", "");

        logger.debug("{} 发送验证码 {}",mobile,content);
        sendHttpRequest(ZhuTongConstans.URL_SEND, paramentMap, "UTF-8", "POST");

    }

    /**
     * 发送普通短信
     * @param mobile
     * @param content
     * @return
     * @throws IOException
     */
    public void sendMessage(String mobile, String content) throws IOException, ZhuTongSMSException, NoSuchAlgorithmException {
        Map paramentMap = new LinkedHashMap();
        String strtime = new SimpleDateFormat("yyyyMMddHHmmss").format(System.currentTimeMillis());
        paramentMap.put("username", username);
        String pass = Md5Tools.md5(Md5Tools.md5(password) + strtime);
        paramentMap.put("tkey",  strtime);
        paramentMap.put("password", pass);//加密后密码
        paramentMap.put("productid", messageProductId);//   普通短信专用产品id
        paramentMap.put("mobile", mobile);//号码
        paramentMap.put("content",  content);//内容
        paramentMap.put("xh",  "");
        logger.debug("{} 发送短信 {}",mobile,content);
        sendHttpRequest(ZhuTongConstans.URL_SEND, paramentMap, "UTF-8", "POST");
    }


    private void sendHttpRequest(String strUrl, Map<String, String> paramentMap, String anaycle, String presendway) throws IOException,ZhuTongSMSException {
        StringBuffer sb = new StringBuffer();
        URL url = new URL(strUrl);
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setDoOutput(true);
        httpConn.setRequestMethod(presendway);
        httpConn.setConnectTimeout(60000);
        httpConn.setReadTimeout(60000);

        StringBuffer parament = new StringBuffer();
        for (Map.Entry entry : paramentMap.entrySet()) {
            if (("".equals(entry.getKey())) || (entry.getKey() == null)) {
                parament.append(URLEncoder.encode((String) entry.getValue(), anaycle) + "&");
            } else if ((((String) entry.getKey()).equalsIgnoreCase("MOBILE")) || (((String) entry.getKey()).equalsIgnoreCase("phone")) ||
                    (((String) entry.getKey()).equalsIgnoreCase("mb")) || (((String) entry.getKey()).equalsIgnoreCase("tele"))) {
                if (((String) entry.getValue()).endsWith(",")) {// 手机号以,结尾
                    parament.append((String) entry.getKey() + "=" + ((String) entry.getValue()).substring(0, ((String) entry.getValue()).length() - 1) + "&");
                } else {
                    parament.append((String) entry.getKey() + "=" + ((String) entry.getValue()) + "&");
                }
            } else if ((((String) entry.getKey()).equalsIgnoreCase("Content")) || (((String) entry.getKey()).equalsIgnoreCase("Message")) || (((String) entry.getKey()).equalsIgnoreCase("ms"))
                    || (((String) entry.getKey()).equalsIgnoreCase("msg_content")) || (((String) entry.getKey()).equalsIgnoreCase("msg")) || (((String) entry.getKey()).equalsIgnoreCase("sms"))
                    || (((String) entry.getKey()).equalsIgnoreCase("smscontent"))|| (((String) entry.getKey()).equalsIgnoreCase("smsg")))
                parament.append((String) entry.getKey() + "=" + URLEncoder.encode((String) entry.getValue(), anaycle) + "&");
            else {
                parament.append((String) entry.getKey() + "=" + (String) entry.getValue() + "&");
            }
        }
        if (("".equals(parament.toString())) || (parament.toString() == null))
            sb.append("9999");
        if (parament.toString().endsWith("&")) {
            parament.setLength(parament.length() - 1);
        }
        httpConn.setRequestProperty("Content-Length", String.valueOf(parament.toString().getBytes().length));
        httpConn.getOutputStream().write(parament.toString().getBytes());
        httpConn.getOutputStream().flush();
        httpConn.getOutputStream().close();
        InputStream is = httpConn.getInputStream();
        BufferedReader bf = new BufferedReader(new InputStreamReader(is,anaycle));
        String tr = "";
        while ((tr = bf.readLine()) != null) {
            sb.append(tr);
        }

        logger.debug("发送短信请求地址:{}",url);


        String result = sb.toString();
        logger.debug("发送短信返回结果:{}",result);
        if(!result.startsWith(ZhuTongConstans.SEND_CODE_SUCCESS)){
            throw new ZhuTongSMSException("发送短信失败 result:"+sb);
        }

    }
}
